package com.zbkj.admin.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.zbkj.admin.service.IAdminStandardHandleService;
import com.zbkj.common.exception.CommonException;
import com.zbkj.common.function.ListsumFunction;
import com.zbkj.common.model.project.EstimateFun;
import com.zbkj.common.model.project.ProjectInfo;
import com.zbkj.common.model.standard.*;
import com.zbkj.common.request.standard.AddleafRequest;
import com.zbkj.common.request.standard.UptStandRequest;
import com.zbkj.common.response.standard.*;
import com.zbkj.service.service.product.ProductService;
import com.zbkj.service.service.project.EstimateFunService;
import com.zbkj.service.service.project.ProjectInfoService;
import com.zbkj.service.service.standard.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther:
 * @Date: 2024/9/16 01:07
 * @Description:
 */
@Service
@Slf4j
public class AdminStandardHandlerServiceImpl implements IAdminStandardHandleService {

    @Autowired
    private IPeStandardService peStandardService;



    @Autowired
    private IPeStandardReleService peStandardReleService;

    @Autowired
    private IPeStandardHumcostService peStandardHumcostService;

    @Autowired
    private AdminProjectHandleV2ServiceImpl adminProjectHandleV2Service;

    private final String fileName = "开发费用估算.xlsx";


    @Override
    public Long addLeaf(AddleafRequest addleafRequest) {
        PeStandard peStandard = new PeStandard();
        BeanUtils.copyProperties(addleafRequest, peStandard);
        peStandard.setStandardType(null);

        peStandardService.save(peStandard);
        return peStandard.getId();
    }

    @Override
    public List<ReportDetailResponse> getReportDetail(Long projectId, HttpServletResponse response) throws Exception {
        List<ReportDetailResponse> reportDetailResponses = adminProjectHandleV2Service.estimateDetail(projectId);
        exportToExcel(reportDetailResponses, fileName);
        extract(response, fileName);
        delFile(fileName);
        return null;
    }

    public void extract(HttpServletResponse response, String fileName) throws Exception{
        File file = new File(fileName);
        response.setContentType("application/octet-stream;charset=utf-8");
        response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(FileUtil.getName(file), "UTF-8"));
        FileInputStream fileInputStream = new FileInputStream(file);
        int len = 0;
        byte[] buffer = new byte[1024];
        OutputStream outputStream = response.getOutputStream();
        while((len=fileInputStream.read(buffer))>0) {
            outputStream.write(buffer, 0, len);
        }
        fileInputStream.close();
        outputStream.flush();
        outputStream.close();
    }

    public void delFile(String fileName){
        File file = new File(fileName);
        file.delete();
    }






    public void exportToExcel(List<ReportDetailResponse> dataList, String fileName) throws Exception {
        // 1. 创建工作簿和工作表
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("开发费用估算");

        // 2. 设置列宽（根据内容调整）
        sheet.setColumnWidth(0, 35 * 256);  // A列
        sheet.setColumnWidth(1, 15 * 256);  // B列
        sheet.setColumnWidth(2, 25 * 256);  // C列
        sheet.setColumnWidth(3, 60 * 256);  // D列

        // 3. 创建样式
        CellStyle formulaStyle = workbook.createCellStyle();

        formulaStyle.setBorderBottom(BorderStyle.MEDIUM);
        formulaStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        formulaStyle.setBorderLeft(BorderStyle.MEDIUM);
        formulaStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        formulaStyle.setBorderRight(BorderStyle.MEDIUM);
        formulaStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
        formulaStyle.setBorderTop(BorderStyle.MEDIUM);
        formulaStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());

        formulaStyle.setAlignment(HorizontalAlignment.CENTER);
        formulaStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        CellStyle textStyle = workbook.createCellStyle();
        textStyle.setWrapText(true);

        // 4. 填充数据
        int rowNum = 0;
        for (ReportDetailResponse item : dataList) {
            // 4.1 处理主项目
            Row row = sheet.createRow(rowNum++);
            if(ObjectUtil.isNotEmpty(item.getChilds())){
                int size = item.getChilds().size() -1;
                for (int i = 0; i < size; i++) {
                    sheet.createRow(rowNum++);
                }
            }
            createMainRow(sheet, item, row, textStyle, formulaStyle);

            // 4.2 处理子项目
            if (item.getChilds() != null) {
                for (int i = 0; i < item.getChilds().size(); i++) {
                    ReportDetailResponse child = item.getChilds().get(i);
                    createChildRow(child, textStyle, formulaStyle, i, row.getRowNum(), sheet);
                }
            }
        }

        // 5. 写入文件
        try (FileOutputStream fos = new FileOutputStream(fileName)) {
            workbook.write(fos);
        }
        workbook.close();
    }

    private void createMainRow(Sheet sheet, ReportDetailResponse item, Row row, CellStyle textStyle, CellStyle formulaStyle) {
        // A列：指标描述
        Cell cell0 = row.createCell(0);
        cell0.setCellValue(item.getKeyDescribe());
        cell0.setCellStyle(textStyle);
        cell0.setCellStyle(formulaStyle);
        // B列：留空
        row.createCell(1);
        List<ReportDetailResponse> childs = item.getChilds();
        boolean mergeB = true;
        //行
        Integer endRow;
        Integer endColumn;
        Integer firstColumn = 0;
        Integer firstRow = row.getRowNum();

        if(ObjectUtil.isNotEmpty(childs)){
            String keyDescribeChild = childs.get(0).getKeyDescribeChild();
            if(! StringUtils.isEmpty(keyDescribeChild)) mergeB = false;
            //行
            endRow = row.getRowNum() + childs.size()-1;
            //列
            endColumn = mergeB? 1:0;
            CellRangeAddress region = new CellRangeAddress(firstRow, endRow, firstColumn, endColumn);
            sheet.addMergedRegion(region);
        }else{
            endRow=row.getRowNum();
            endColumn=1;
            CellRangeAddress region = new CellRangeAddress(firstRow, endRow, firstColumn, endColumn);
            sheet.addMergedRegion(region);
        }
        // 为合并区域所有单元格设置样式
        for (int r = firstRow; r <= endRow; r++) {
            Row rowImte = sheet.getRow(r) == null ? sheet.createRow(r) : sheet.getRow(r);
            for (int c = firstColumn; c <= endColumn; c++) {
                Cell cell = rowImte.getCell(c) == null ? rowImte.createCell(c) : rowImte.getCell(c);
                cell.setCellStyle(formulaStyle);
            }
        }


        // C列：公式/值
        Cell cell2 = row.createCell(2);
        if (item.getValue() != null) {
            cell2.setCellValue(item.getValue());
            cell2.setCellStyle(formulaStyle);
        }

        // D列：参数说明
        Cell cell3 = row.createCell(3);
        cell3.setCellValue(item.getParam() != null ? item.getParam() : "");
        cell3.setCellStyle(textStyle);
        cell3.setCellStyle(formulaStyle);
    }

    private void createChildRow(ReportDetailResponse child, CellStyle textStyle, CellStyle formulaStyle, int i, int parentRowNum, Sheet sheet) {
        int rowNum = parentRowNum+i;
        Row row = sheet.getRow(rowNum);

        if(ObjectUtil.isNotEmpty(child.getKeyDescribeChild())){
            // B列：子项描述
            Cell cell1 = row.createCell(1);
            cell1.setCellValue(child.getKeyDescribeChild());
            cell1.setCellStyle(textStyle);
            cell1.setCellStyle(formulaStyle);
        }

        // C列：公式/值
        Cell cell2 = row.createCell(2);
        if (child.getValue() != null) {
            cell2.setCellValue(child.getValue());
            cell2.setCellStyle(formulaStyle);
        }

        // D列：参数说明
        Cell cell3 = row.createCell(3);
        cell3.setCellValue(child.getParam() != null ? child.getParam() : "");
        cell3.setCellStyle(textStyle);
        cell3.setCellStyle(formulaStyle);
    }

    @Override
    public List<ProductivityResponse> productivity(Long standardId) {
        List<PeStandardRele> list = peStandardReleService.lambdaQuery().eq(PeStandardRele::getStandardId, standardId).list();
        Map<String, List<PeStandardRele>> collect = list.stream().collect(Collectors.groupingBy(PeStandardRele::getBusinessType));
        List<ProductivityResponse> response = new ArrayList<>();
        for (Map.Entry<String, List<PeStandardRele>> entry : collect.entrySet()) {
            String key = entry.getKey();
            List<PeStandardRele> value = entry.getValue();
            ProductivityResponse productivityResponse = new ProductivityResponse();
            List<ProductivityInnerResponse> innerList = new ArrayList<>();
            value.forEach(item -> {
                ProductivityInnerResponse productivityInnerResponse = new ProductivityInnerResponse();
                BeanUtils.copyProperties(item, productivityInnerResponse);
                innerList.add(productivityInnerResponse);
            });
            innerList.sort(Comparator.comparing(ProductivityInnerResponse::getYear).reversed());
            productivityResponse.setYearData(innerList);
            productivityResponse.setBusinessType(key);
            response.add(productivityResponse);
        }
        return response;
    }

    @Override
    public List<HumcoutResponse> humcost(Long standardId) {
        List<PeStandardHumcost> list = peStandardHumcostService.lambdaQuery().eq(PeStandardHumcost::getStandardId, standardId).list();
        Map<String, List<PeStandardHumcost>> collect = list.stream().collect(Collectors.groupingBy(PeStandardHumcost::getCity));
        List<HumcoutResponse> response = new ArrayList<>();
        for (Map.Entry<String, List<PeStandardHumcost>> entry : collect.entrySet()) {
            String key = entry.getKey();
            List<PeStandardHumcost> value = entry.getValue();
            HumcoutResponse humcoutResponse = new HumcoutResponse();
            List<HumcoutInnerResponse> innerList = new ArrayList<>();
            value.forEach(item -> {
                HumcoutInnerResponse humcoutInnerResponse = new HumcoutInnerResponse();
                BeanUtils.copyProperties(item, humcoutInnerResponse);
                innerList.add(humcoutInnerResponse);
            });
            innerList.sort(Comparator.comparing(HumcoutInnerResponse::getYear).reversed());
            humcoutResponse.setYearData(innerList);
            humcoutResponse.setCity(key);
            response.add(humcoutResponse);
        }
        return response;
    }

    @Override
    public void uptStandard(List<UptStandRequest> uptStandRequestLs) {
        if(ObjectUtil.isEmpty(uptStandRequestLs)){
            throw new CommonException("更新标准标准不能为空");
        }
        List<PeStandard> toUptList = ListUtils.newArrayList();
        uptStandRequestLs.forEach(item -> {
            PeStandard peStandard = new PeStandard();
            BeanUtils.copyProperties(item, peStandard);
            toUptList.add(peStandard);
        });
        peStandardService.updateBatchById(toUptList);
    }
}
